#
# catalog.py 
#
# Module controls public interface to an eCataloger application
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Copyright 2009,2010- Jeremy Nelson, Tomichi Informatics LLC
#
# Import statements
import cgi,logging,sys
import datetime,os
import wsgiref.handlers


from google.appengine.ext import db
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import login_required
from google.appengine.api import memcache
from django.utils import simplejson
from common.app_info import *
from catalog_manager import *
import common.templatefilters
import FRBRData,MODSData

webapp.template.register_template_library('common.templatefilters')

class ApplicationCache():
    ''' Creates and stores standard and proxy views of E-Library in cache.
        Standard view for users access application from within IP range
        of insitution, proxy view for users access resources from outside
        of IP range.'''
    def __init__(self,**args):
        if args.has_key('cache_view'):
            self.cache_view = args['cache_view']
        else:
            self.cache_view = 'standard'

    def get_resource_titles(self,*args):
        lang_alphabet = args[1]
        resources = args[0]
        if lang_alphabet == 'eng':
            output_dict = {'a':[],'b':[],'c':[],'d':[],
                           'e':[],'f':[],'g':[],'h':[],
                           'i':[],'j':[],'k':[],'l':[],
                           'm':[],'n':[],'o':[],'p':[],
                           'q':[],'r':[],'s':[],'t':[],
                           'u':[],'v':[],'w':[],'w':[],
                           'y':[],'z':[]}
        else:
            output_dict = dict()
        for entity in resources:
            title_letter = entity.title.title[0].lower()
            if output_dict.has_key(title_letter):
                output_dict[title_letter].append(entity)
            else:
                output_dict[title_letter] = [entity]
        return output_dict

    def get_views(self,**args):
        if args.has_key('template'):
            template = args['template']
        else:
            template = 'public.html'
        app_cache = memcache.get(self.cache_view)
        if app_cache is not None:
            return app_cache
        else:
            app_cache = self.generate_views(template)
            if not memcache.set(self.cache_view,app_cache):
                logging.error("Memcache set failed for %s view" %\
                              self.cache_view)
        return app_cache

    def generate_views(self,*args):
        template_file = args[0]
        if not template_file:
            template_file = 'public.html'
        purchased_resources = FRBRData.PurchasedElectronicResourceEndeavor.all()
        free_websites = FRBRData.WebSiteEndeavor.all()
        all_resources = purchased_resources.fetch(1000) + free_websites.fetch(1000)
        resource_info = {'total_purchased':purchased_resources.count(),
                         'total_free':free_websites.count()}
        
        popular_resources = []
        all_concepts = {}
        trials = []
        concepts = FRBRData.Concept.all().order("display_form")
        for concept in concepts:
            concept_dict = {'display_form':concept.display_form,
                            'resources':[]}
            all_concepts[str(concept.key())] = concept_dict
        output_dict = {'a':[],'b':[],'c':[],'d':[],
                       'e':[],'f':[],'g':[],'h':[],
                       'i':[],'j':[],'k':[],'l':[],
                       'm':[],'n':[],'o':[],'p':[],
                       'q':[],'r':[],'s':[],'t':[],
                       'u':[],'v':[],'w':[],'w':[],
                       'y':[],'z':[]}
        for resource in all_resources:
            if resource.manifestation.popularity > 75:
                popular_resources.append(resource)
            for subject_key in resource.work.subjects:
                if all_concepts.has_key(str(subject_key)):
                    resource_key = "%s" % str(resource.key())
                    #all_concepts[str(subject_key)]['resources'].append(resource_key)
                    all_concepts[str(subject_key)]['resources'].append(resource)
            first_letter = resource.title.title[0].lower()
            if resource.manifestation.is_trial:
                trials.append(resource)
            if output_dict.has_key(first_letter):
                #output_dict[first_letter].append(str(resource.key()))
                output_dict[first_letter].append(resource)
        output_concepts = list()
        for row in all_concepts.values():
            row['resources'] = sorted(row['resources'],
                                      key=lambda x: x.title.title)
            output_concepts.append(row)
        app_info_query = ApplicationAndHelpData.AppInfo.all()
        if app_info_query.count() > 0:
            app_info = app_info_query[0]
        else:
            app_info = None
        query = db.GqlQuery("SELECT * FROM HelpTopics WHERE type_of=:1 ORDER BY question",
                            "howdoi")
        help_topics = query.fetch(1000)
        template_values = {
            'app_view':self.cache_view,
            'howdois':help_topics,
            'concepts':sorted(output_concepts,
                              key=lambda x: x['display_form']),
            'app_info':app_info,
            'resource_info':resource_info,
            'popular_resources':sorted(popular_resources,key=lambda x: x.title.title),
            'resource_titles':sorted(output_dict.items(),key=lambda x: x[0]),
            'trials':sorted(trials,key=lambda x: x.title.title)}

        path = os.path.join(os.path.dirname(__file__),
                            'templates/%s' % template_file)
        return template.render(path,template_values)
        
        
class AltTreeViewPage(webapp.RequestHandler):

    def get(self):
        self.response.out.write(ApplicationCache().generate_views('public2.html'))


class ClassicPage(webapp.RequestHandler):
    """ First UI view of E-Library using new 1.2 data models."""

    def get(self):
        """ Standard GET response for public view, vary depending on user's
            IP address.
        """
        user_ip = self.request.remote_addr
        app_info_query = ApplicationAndHelpData.AppInfo.all()
        if app_info_query.count() > 0:
            app_info = app_info_query[0]
        else:
            app_info = None
            cache_view = 'standard'
        if app_info:
            if user_ip >= app_info.start_ip_addr and\
               user_ip <= app_info.end_ip_addr:
                cache_view = 'standard'
            else:
                cache_view = 'proxy'
        self.response.out.write(ApplicationCache(cache_view=cache_view).get_views(template='classic_index.html'))
            

class ClassicResourceListPage(webapp.RequestHandler):
    """ Provides listing of resource, filtered by facet using original E-Library
        view with eCataloger 1.2 data classes.
    """

    def get(self):
        """ Standard GET response, uses method of catalog_manage to extract
             listing of resources.
        """
        resource_filter = self.request.get('filter')
        resources = RPCMethods().getCollection(resource_filter)['collection']
        template_values = {
            'filter': resource_filter,
            'endeavors': resources}
        path = os.path.join(os.path.dirname(__file__),
                            'templates/classic_resource_list.html')
        self.response.out.write(template.render(path,template_values))
        

class HomePage(webapp.RequestHandler):
    ''' Default view for public view '''

    def get(self):
        ''' Standard GET response for public view '''
        user_ip = self.request.remote_addr
        app_info_query = ApplicationAndHelpData.AppInfo.all()
        if app_info_query.count() > 0:
            app_info = app_info_query[0]
        else:
            app_info = None
            cache_view = 'standard'
        if app_info:
            if user_ip >= app_info.start_ip_addr and\
               user_ip <= app_info.end_ip_addr:
                cache_view = 'standard'
            else:
                cache_view = 'proxy'
        self.response.out.write(ApplicationCache(cache_view=cache_view).get_views())                      
  
application = webapp.WSGIApplication([
    ('/',ClassicPage),
    ('/classic',ClassicPage),
    ('/classic/list',ClassicResourceListPage),
    ('/alt',AltTreeViewPage),
    ('/rpc',RPCHandler),
    ('/jquery',jQueryHandler)],debug=True)

def main():
    wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
    main()
